// 
// SoapTrace.Net - A soap message monitoring utility. 
// 
// Copyright (C) 2004 Matthew Ward
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// Matthew Ward (mrward@users.sourceforge.net)
// 

using NUnit.Framework;
using System;
using WinPcap;
using WinPcap.Tests.Utils;

namespace WinPcap.Tests
{
	/// <summary>
	/// Tests the EthernetPacket class.
	/// </summary>
	[ TestFixture ]
	public class EthernetPacketTestFixture
	{
		/// <summary>
		/// Tests a Tcp SYN packet.
		/// </summary>
		[ Test ]
		public void TcpSynPacket( )
		{
			string Data = 
				"0000  00 90 F5 2B 8D 2F 00 40  F4 8C AA 2F 08 00 45 00 \n" +
				"0010  00 30 45 C0 40 00 80 06  23 02 C8 01 01 01 C8 01 \n" +
				"0020  01 02 04 4A 1B 5A D0 22  05 0A 00 00 00 00 70 02 \n" +
				"0030  FF FF FC 48 00 00 02 04  05 B4 01 01 04 02 ";
	
			byte[ ] Bytes = TestUtility.GetBytesFromString( Data ); 

			EthernetPacket Packet = new EthernetPacket( Bytes );

			// Check the byte count.

			Assert.AreEqual( Bytes.Length,
				Packet.GetBytes( ).Length,
				"Ethernet packet byte count is incorrect." );

			// Check the packet type.

			Assert.AreEqual( EthernetPacketType.IP,
				Packet.PacketType,
				"Packet type is incorrect." );

			// Check the packet addresses.

			Assert.AreEqual( "00:90:F5:2B:8D:2F",
				Packet.Destination,
				"Ethernet packet destination is incorrect." );
			
			Assert.AreEqual( "00:40:F4:8C:AA:2F",
				Packet.Source,
				"Ethernet packet source is incorrect." );

			// Check that there is an inner packet.

			Assert.IsNotNull( Packet.InnerPacket, "No inner packet." );
		
			// Check inner packet type.

			Assert.AreSame( typeof( IPPacket ), 
				Packet.InnerPacket.GetType( ),
				"Inner packet should be an IP packet." );

			// Check the IP packet's bytes are correct.

			byte[ ] IPPacketBytes = Packet.InnerPacket.GetBytes( );

			// Compare the length.

			Assert.AreEqual( Bytes.Length - EthernetPacket.HeaderLength,
				IPPacketBytes.Length,
				"IP byte count is incorrect." );

			// Compare the actual bytes.

			TestUtility.CompareBytes( Bytes, 
				EthernetPacket.HeaderLength,
				IPPacketBytes,
				0,
				Bytes.Length - EthernetPacket.HeaderLength );
		}

		/// <summary>
		/// Tests an ethernet packet that is not big enough to hold
		/// the ethernet header.
		/// </summary>
		[ Test ]
		public void InvalidPacket( )
		{
			string Data = 
				"0000  00 90 F5 2B 8D 2F 00 40  F4 8C AA 2F 08";
	
			byte[ ] Bytes = TestUtility.GetBytesFromString( Data ); 

			EthernetPacket Packet = new EthernetPacket( Bytes );
				
			// Check packet type.
			Assert.AreEqual( EthernetPacketType.None,
				Packet.PacketType,
				"Packet should be of an unknown type." );

			// Check destination is blank.
			Assert.AreEqual( "", 
				Packet.Destination, 
				"Packet destination should be blank." );

			// Check source is blank.
			Assert.AreEqual( "", 
				Packet.Source, 
				"Packet source should be blank." );

			// Check that there is no inner packet.

			Assert.IsNull( Packet.InnerPacket, "Should not be an inner packet." );
		}

		/// <summary>
		/// Tests that an ethernet packet with a valid header, but
		/// payload data is handled.  Technially an ethernet packet
		/// should be at least 64 bytes.
		/// </summary>
		[ Test ]
		public void PacketWithNoPayloadData( )
		{
			string Data = 
				"0000  00 90 F5 2B 8D 2F 00 40  F4 8C AA 2F 08 00";

			byte[ ] Bytes = TestUtility.GetBytesFromString( Data ); 

			EthernetPacket Packet = new EthernetPacket( Bytes );

			// Check the byte count.

			Assert.AreEqual( Bytes.Length,
				Packet.GetBytes( ).Length,
				"Ethernet packet byte count is incorrect." );

			// Check the packet type.

			Assert.AreEqual( EthernetPacketType.IP,
				Packet.PacketType,
				"Packet type is incorrect." );

			// Check the packet addresses.

			Assert.AreEqual( "00:90:F5:2B:8D:2F",
				Packet.Destination,
				"Ethernet packet destination is incorrect." );
			
			Assert.AreEqual( "00:40:F4:8C:AA:2F",
				Packet.Source,
				"Ethernet packet source is incorrect." );

			// Check that there is no inner packet.

			Assert.IsNull( Packet.InnerPacket, "Should not be an inner packet." );
		}
	}
}
